package com.minelx.util.date;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

public class Month {

	private final Clock clock;

	Month(Clock clock) {
		this.clock = clock;
	}

	public Stream<Day> days() {
		Day firstDayOfThisMonth = day(1);
		Day firstDayOfNextMonth = offset(1).day(1);
		return firstDayOfThisMonth.daysBetween(firstDayOfNextMonth);
	}

	public List<Month> monthsBetween(Month destination) {
		List<Month> result = new LinkedList<>();
		Month current = this;
		while (!current.equals(destination)) {
			result.add(current);
			current = current.offset(1);
		}
		return result;
	}

	public Stream<Month> months() {
		return clock.offsets(ClockUnit.MONTH, 1)
				.map(Month::new);
	}

	public Day day(int at) {
		return new Day(clock.locate(ClockUnit.DAY, at));
	}

	public String format(String pattern) {
		return clock.format(pattern);
	}

	public Month offset(int amount) {
		return new Month(clock.offset(ClockUnit.MONTH, amount));
	}

	public static Month of(int year, int month) {
		// first day of this month
		return new Month(Clock.of(year, month, 1));
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		Month month = (Month) o;
		return clock.equals(month.clock);
	}

	@Override
	public int hashCode() {
		return Objects.hash(clock);
	}
}
